package com.ruoyi.project.shortUrl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.http.HttpClientUtil;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.shortUrl.cache.ShortCodeCache;
import com.ruoyi.project.shortUrl.cache.ShortCodeCacheEntity;
import com.ruoyi.project.shortUrl.config.domain.ShortConfig;
import com.ruoyi.project.shortUrl.config.service.ShortConfigService;
import com.ruoyi.project.shortUrl.third.domain.ThirdShort;
import com.ruoyi.project.shortUrl.third.mapper.ThirdShortMapper;
import com.ruoyi.project.shortUrl.url.domain.ShortUrl;
import com.ruoyi.project.shortUrl.url.service.IShortUrlService;
import com.ruoyi.project.shortUrl.util.ShortUrlRoleKey;
import com.ruoyi.project.system.user.domain.User;

@Controller
@RequestMapping("/cn")
public class FrameController extends BaseController
{
	
	private static final String createFailMsg = "转换失败了！";
	private static final Logger logger = LoggerFactory.getLogger(FrameController.class);
	
	@Autowired
	private ShortCodeCache shortCodeCache;
	
	@Autowired
	private IShortUrlService shortUrlService;
	
	@Autowired
	private ShortConfigService shortConfigService;
	
	@Autowired
	private ThirdShortMapper thirdShortMapper;
	
    @GetMapping("/to/{shortCode}")
    public String login(@PathVariable("shortCode") String shortCode, ModelMap map)
    {
    	ShortCodeCacheEntity cache = shortCodeCache.get(shortCode);
    	if(cache!=null) {
    		map.put("cache", cache);
            return "frame";
    	}else {
    		return "error/404";
    	}
    }
    
    @GetMapping("/index")
    public String index(ModelMap map)
    {
    	ShortConfig filter = new ShortConfig();
    	filter.setType("caption");
    	map.put("captions", shortConfigService.getShortConfigList(filter));
    	map.put("defaultOpenWay", shortConfigService.getTARGET_URL_OPEN_WAY().toString());
    	map.put("openThird", Boolean.valueOf(shortConfigService.getConfigValue("third_short")));
    	
    	String third_name = shortConfigService.getConfigValue("third_name");
    	map.put("thirdName", StringUtils.isNotBlank(third_name)?third_name:"第三方接口");
		return "frame/index";
    }
    
    @GetMapping("/index2")
    public String index2(ModelMap map)
    {
    	if(!Boolean.valueOf(shortConfigService.getConfigValue("third_short"))) {
    		return index(map);
    	}
    	ShortConfig filter = new ShortConfig();
    	filter.setType("caption");
    	map.put("captions", shortConfigService.getShortConfigList(filter));
    	
    	ThirdShort filter2 = new ThirdShort();
    	filter2.setVisable(true);
    	map.put("thirds", thirdShortMapper.selectThirdShortList(filter2));
    	
    	String third_name = shortConfigService.getConfigValue("third_name");
    	map.put("thirdName", StringUtils.isNotBlank(third_name)?third_name:"第三方接口");
		return "frame/index2";
    }
    
    @GetMapping("/contact")
    public String contact(ModelMap map)
    {
    	ShortConfig wx = shortConfigService.getConfig("wx");
    	map.put("wx", wx==null?"":wx.getValue());
    	
    	ShortConfig qq = shortConfigService.getConfig("qq");
    	map.put("qq", qq==null?"":qq.getValue());
    	
		return "frame/contact";
    }
    
    @GetMapping("/msgrd")
    public String msgrd(ModelMap map)
    {
    	ShortConfig qq = shortConfigService.getConfig("qq");
    	map.put("qq", qq==null?"":qq.getValue());
    	
		return "frame/msgrd";
    }
    
    /**
     * 新增保存短链接
     */
    @PostMapping("/create")
    @ResponseBody
    public AjaxResult create(@RequestParam(value = "targetUrl[]")String[] targetUrl, String openType, Boolean useSecondShort)
    {
    	logger.info("开始创建短链接");
    	String userType = "";
    	User u = null;
		try {
			//登录了，肯定是注册用户或者管理员
			u = ShiroUtils.getSysUser();
		} catch (Exception e1) {
		}
		
		//没有登录，只能以非注册用户使用
		if(u==null) {
			userType = ShortUrlRoleKey.NOT_REGISTER;
		}else {
			userType = u.getShortUserType();
		}
		
		List<String> result = new ArrayList<>();
		for(String target:targetUrl) {
			if(StringUtils.isNotBlank(target)) {
				ShortUrl shortUrl = new ShortUrl();
				shortUrl.setTargetUrl(target);
				try {
					result.add(shortUrlService.createShortUrlReturnShortUrl(userType, shortUrl, -1, openType));
				} catch (Exception e) {
					result.add(createFailMsg+e.getMessage());
				}
			}
		}
		logger.info("使用本地生成：结果"+String.join(",", result));
		
		if(useSecondShort) {
			ThirdShort filter = new ThirdShort();
	    	filter.setUseDefault(true);
	    	List<ThirdShort> list = thirdShortMapper.selectThirdShortList(filter);
	    	if(CollectionUtils.isNotEmpty(list)) {
	    		ThirdShort defaultThird = list.get(0);
	    		String[] targetUrls = new String[result.size()];
	    		result.toArray(targetUrls);
	    		result = thirdWayShort(targetUrls, defaultThird.getId());
	    	}
	    	
		}
		
        return AjaxResult.success(result);
    }
    
    @PostMapping("/third")
    @ResponseBody
    public AjaxResult third(@RequestParam(value = "targetUrl[]")String[] targetUrl, Long thirdId)
    {
    	logger.info("使用第三方接口");
		return AjaxResult.success(thirdWayShort(targetUrl, thirdId));
    }
    
    @RequestMapping(value = "/img",produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public byte[] getImage(String imgType) throws IOException {
    	byte[] bytes = null;
    	ShortConfig config = shortConfigService.getConfig(imgType);
    	if(config!=null && StringUtils.isNotBlank(config.getValue())) {
    		FileInputStream inputStream = null;
    		try {
				String filePath = config.getValue();
				File file = new File(filePath);
				if(file.exists()) {
					inputStream = new FileInputStream(file);
					bytes = new byte[inputStream.available()];
					inputStream.read(bytes, 0, inputStream.available());
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if(inputStream!=null) {
					inputStream.close();
				}
			}
    	}
    	
        return bytes;
    }
    
    private List<String> thirdWayShort(String[] targetUrl, Long thirdId) {
    	ThirdShort third = thirdShortMapper.selectThirdShortById(thirdId);
    	
    	List<String> result = new ArrayList<>(targetUrl.length);
    	if(third==null) {
    		result.add("请选择一个正确的接口！");
    		return result;
    	}
    	for(String longUrl:targetUrl) {
    		String thisResult = createFailMsg;
    		try {
    			Map<String, String> params = new HashMap<String, String>();
				if(StringUtils.isNotBlank(third.getParam())) {
					String[] strs = third.getParam().split("&");
					for(String str:strs) {
						if(StringUtils.isNotBlank(str)) {
							String[] ky = str.split("=");
							if(ky.length==2) {
								String k = ky[0];
								String v = ky[1];
								if(v.contains("{url}")) {
									v = v.replaceAll("\\{url\\}", longUrl);
								}
								if(third.getUrlencode()) {
									v = URLEncoder.encode(v, "UTF-8");
								}
								params.put(k, v);
							}
						}
					}
				}
    			if("post".equals(third.getMethod().toLowerCase())) {
    				thisResult = HttpClientUtil.sendPostByForm(third.getApi(), params, 1);
    			}else {
    				thisResult = HttpClientUtil.sendGet(third.getApi(), params);
    			}
    			
    			if(StringUtils.isNotBlank(third.getParsekey())) {
    				String[] keys = third.getParsekey().split(",");
    				for(int i=0; i<keys.length; i++) {
    					String k = keys[i];
    					JSONObject jsonObject = JSONObject.parseObject(thisResult);
    					thisResult = jsonObject.getString(k);
    				}
    			}
			} catch (Exception e) {
				e.printStackTrace();
				thisResult = createFailMsg;
			}
    		
    		result.add(thisResult);
    	}
    	
    	return result;
    }
}
